import pandas as pd
from sklearn.ensemble import IsolationForest
import matplotlib.pyplot as plt

# 加载数据
file_path = r"C:\Users\18318\Desktop\goldstock_v2_cleaned.csv"
data = pd.read_csv(file_path)

# 打印列名以检查是否存在'Date'列
print("列名列表：", data.columns.tolist())

# 移除'Unnamed: 0'列，因为它通常是无用的索引列
data = data.drop(columns=['Unnamed: 0'])

# 将'Date'列转换为datetime类型，然后转换为数值型特征（如果需要）
data['Date'] = pd.to_datetime(data['Date'])
data['Year'] = data['Date'].dt.year
data['Month'] = data['Date'].dt.month

# 移除原始的'Date'列
data = data.drop(columns=['Date'])

# 确保所有列都是数值型
for col in data.columns:
    if data[col].dtype == 'object':
        data[col] = pd.to_numeric(data[col], errors='coerce')

# 移除任何包含NaN的行
data = data.dropna()

# 检查数据框是否为空
if data.empty:
    print("数据框为空，无法进行异常值检测。")
else:
    # 使用IsolationForest检测异常值
    clf = IsolationForest(contamination='auto', n_estimators=100, random_state=42)
    clf.fit(data)

    # 预测数据集中每个点是否为异常值
    predictions = clf.predict(data)

    # 将预测结果添加到原始数据框中
    data['anomaly'] = predictions

    # 可以选择保存带有异常值标签的数据框
    data.to_csv(r"C:\Users\18318\Desktop\goldstock_v2_anomalies.csv", index=False)

    # 打印出异常值
    anomalies = data[data['anomaly'] == -1]
    print(anomalies)

    # 异常值数据
    anomalies = data[data['anomaly'] == -1]

    # 打印异常值的统计信息
    print(anomalies.describe())

    # 可视化异常值
    plt.figure(figsize=(14, 7))
    plt.subplot(1, 2, 1)
    plt.scatter(anomalies['Close/Last'], anomalies['Volume'], alpha=0.5)
    plt.title('Close/Last vs Volume - Anomalies')

    plt.subplot(1, 2, 2)
    plt.scatter(anomalies['High'], anomalies['Low'], alpha=0.5)
    plt.title('High vs Low - Anomalies')

    plt.tight_layout()
    plt.show()